const path = require('path');
const PATH_SEP = path.sep;

function includesSameCirculation(circulations, c) {
  return circulations.some(item => {
    // 链路长度最低为2，即自己require自己，数组中两个元素都是自己
    // 链路长度3开始，若是链路的头尾一致则为相同的环
    return item.length >= 3 && c.length >= 3 && c[0] === item[0] &&
        c[c.length - 2] === item[item.length - 2];
  });
}

function extractCommonPrefix(arr) {
  let index = 0;
  const paths = arr.map(item => item.split(PATH_SEP));
  w: while (true) {
    const path = paths[0][index];
    for (const p of paths) {
      if (index >= p.length - 1 || p[index] !== path) {
        // 至少保留最后一个文件名，其他作为前缀
        break w;
      }
    }
    index++;
  }

  const prefix = paths[0].slice(0, index).join(PATH_SEP);
  const suffix = paths.map(item => item.slice(index).join(PATH_SEP));
  if (suffix.every(item => !item)) {
    return {
      prefix: '',
      paths: arr,
    };
  }

  return {
    prefix,
    paths: suffix,
  };
}

function once(fn) {
  let done = false;
  return function() {
    if (!done) {
      done = true;
      return fn(...arguments);
    }
  };
}

function formatBadRequireChain(array) {
  const res = array;
  if (res.length) {
    res.push(res[0]);
  }
  return res.map(item => item.filename);
}

function isEmptyExport(exports) {
  return exports != null && Object.keys(exports).length === 0 &&
      exports.constructor === Object;
}

const escape = '\u001b[';
const style = (str, code0, code1) => `${escape}${code0}m${str}${escape}${code1}m`;
const buildStyle = (code0, code1) => (str) => style(str, code0, code1);

const underline = buildStyle(4, 24);
const bold = buildStyle(1, 22);
const cyan = buildStyle(36, 39);
const red = buildStyle(31, 39);

module.exports = {
  includesSameCirculation,
  extractCommonPrefix,
  once,
  formatBadRequireChain,
  isEmptyExport,
  underline,
  bold,
  cyan,
  red,
};
